import { getSage, hasProperties } from '../cli/utils/utils.js';
import K from 'node:fs/promises';
import _ from 'node:os';
import { Colors, CommandInteraction, Message, ButtonInteraction, PartialGroupDMChannel, ChannelType, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js';
import { client } from './robo.js';
import { logger } from './logger.js';
import { env } from './env.js';
import { URL } from 'node:url';
import { getState, setState } from './state.js';
import { isMainThread, parentPort } from 'node:worker_threads';
import { STATE_KEYS, discordLogger } from './constants.js';
import L from 'node:path';
import { color } from './color.js';

const l="robo_debug_",E=10,Z=process.env.NODE_ENV!=="production",ee=/\x1b\[.*?m/g,be=async n=>{await n.deferReply();const e=logger.getRecentLogs().map(t=>t.message()),s=(getState(l+"error_counter")??-1)+1;setState(l+"error_counter",s),setState(`${l}_error_${s}`,{logs:e}),D(s,0,n,"new");},Ie={description:"View most recent logs",sage:{defer:!1}},$e=async n=>{await n.reply({content:"```bash\nRestarting...\n```"}),setState(STATE_KEYS.restart,{channelId:n.channelId,guildId:n.guildId,startTime:Date.now()}),isMainThread?process.send?.({type:"restart"}):parentPort?.postMessage({event:"restart",payload:"trigger"});},ye={description:"Restart this Robo",sage:{defer:!1}},_e=()=>{let n=client.uptime/1e3;const e=Math.floor(n/86400),o=Math.floor(n/3600);n%=3600;const s=Math.floor(n/60),t=Math.floor(n%60);let r="";e>0&&(r+=`${e} days, `),o>0&&(r+=`${o} hours, `),s>0&&(r+=`${s} minutes, `),t>0&&(r+=`${t} seconds`),r=r.replace(/, $/,"");const a=process.cpuUsage(),u=((a.user+a.system)/1e6).toFixed(2),m=process.memoryUsage().rss/(1024*1024),p=_.totalmem()/(1024*1024*1024),d=_.freemem()/(1024*1024*1024);return {embeds:[{title:"Bot Status",color:Colors.Blurple,fields:[{name:"Uptime",value:r,inline:!0},{name:"Ping",value:`${client.ws.ping}ms`,inline:!0},{name:"\u200B",value:"\u200B",inline:!0},{name:"CPU Usage",value:`${u}%`,inline:!0},{name:"RAM Usage",value:`${m.toFixed(2)} MB`,inline:!0},{name:"\u200B",value:"\u200B",inline:!0},{name:"Total RAM",value:`${p.toFixed(2)} GB`,inline:!0},{name:"Available RAM",value:`${d.toFixed(2)} GB`,inline:!0},{name:"\u200B",value:"\u200B",inline:!0},{name:"Operating System",value:`${_.platform()} ${_.version()} ${_.arch()} (${_.release()})`,inline:!1}]}]}},Ce={description:"View status of this Robo"};async function Ee(n,e,o,s){const{errorChannelId:t,errorMessage:r,errorReplies:a=!0}=getSage();if(discordLogger.debug("Error response:",n),!(!Z||!a)&&!(!(e instanceof CommandInteraction)&&!(e instanceof Message)&&!(e instanceof ButtonInteraction)))try{const{message:u}=await V({error:n,interaction:e,details:o,event:s});if(t){const m=client.channels.cache.get(t);if(!m){discordLogger.error("No error channel found with ID:",t);return}await m.send(u),r?await W({content:r},e):discordLogger.warn(`Set ${color.bold("errorMessage")} in your Sage config to send a default error reply to the user`);}else await W(u,e);}catch(u){discordLogger.debug("Error printing error response:",u);}}async function W(n,e){if(e instanceof CommandInteraction||e instanceof ButtonInteraction)return e.replied||e.deferred?e.followUp(n):e.reply(n);if(e instanceof Message&&!(e.channel instanceof PartialGroupDMChannel))return e.channel.send(n)}async function ve(n){try{const{errorChannelId:e}=getSage(),o=client.guilds.cache.get(env.get("discord.guildId")),s=o?.channels?.cache?.get(env.get("discord.debugChannelId")??e);if(!o||!s)return discordLogger.warn(`Fix the error or set ${color.bold("DISCORD_GUILD_ID")} and ${color.bold("DISCORD_DEBUG_CHANNEL_ID")} environment variables to prevent your Robo from stopping.`),!1;if(s.type!==ChannelType.GuildText)return discordLogger.warn("Debug channel specified is not a text-based channel."),!1;const{message:t}=await V({error:n});return await s.send(t),discordLogger.debug(`Message sent to channel ${env.get("discord.debugChannelId")} in guild ${env.get("discord.guildId")}.`),!0}catch(e){return discordLogger.error("Error sending message:",e),!0}}const ne=/at .* \((.*):(\d+):(\d+)\)/;async function H(n,e){try{const o=n.stack?.split(`
`);if(o?.shift(),!o)throw new Error("No stack trace found");const s=L.sep+"node_modules"+L.sep,t=o.findIndex(g=>g.includes(s));if(e==="dependency"&&t>0&&o[t].includes(s+"robo.js/"))return null;const r=g=>{const I=g.trim();return I&&!I.includes(s)&&!I.includes("node:")&&I.includes(":")&&I.includes(L.sep)},a=e==="dependency"?o[t]:o.find(r),[,u,m,p]=a.match(ne)||[];if(!u||!m||!p)throw new Error("Could not parse stack trace");const d=u.replaceAll("/.robo/build/commands","").replaceAll("/.robo/build/events","");let c=d.startsWith("file:")?decodeURI(new URL(d).pathname):d;c.startsWith("/")&&process.platform==="win32"&&(c=c.slice(1));const R=(await K.readFile(c,"utf-8")).split(`
`),h=parseInt(m,10),k=parseInt(p,10),i=Math.min(h+2,R.length),v=i.toString().length;let y="";for(let g=Math.max(h-3,0);g<i;g++){const I=(g+1).toString().padStart(v," ");y+=`${I} | ${R[g]}
`,g===h-1&&(y+=" ".repeat(k+v+2)+`^
`);}const A=c.length+e.length+10+5;return y.length+A>1024&&(y=y.slice(0,1021-A)+"..."),{code:y,file:c,type:d.endsWith(".ts")?"ts":"js"}}catch(o){return discordLogger.debug("Error getting code at fault:",o),null}}async function V(n){const{details:e,error:o,event:s,interaction:t}=n,{errorChannelId:r}=getSage();let a="There was an error while executing this command!";o instanceof Error?a=o.message:typeof o=="string"&&(a=o),a=a.replace(ee,""),a+=`
\u200B`;const u=logger.getRecentLogs().map(i=>i.message()),m=o instanceof Error?o.stack:null,p=o instanceof Error?await H(o,"dependency"):null,d=o instanceof Error?await H(o,"source"):null,c=[];if(t instanceof CommandInteraction){const i=[t.commandName];if(hasProperties(t.options,["getSubcommandGroup"]))try{i.push(t.options.getSubcommandGroup());}catch{}if(hasProperties(t.options,["getSubcommand"]))try{i.push(t.options.getSubcommand());}catch{}r&&(c.push({name:"Channel",value:`<#${t.channelId}>`}),c.push({name:"User",value:`<@${t.user.id}>`})),c.push({name:"Command",value:"`/"+i.filter(Boolean).join(" ")+"`"});}if(e&&c.push({name:"Details",value:e}),s){const i=d?.file?.replace(process.cwd(),"")??s.path;c.push({name:"Event",value:"`"+i+"`"});}if(p){const i=p.file.replace(process.cwd(),"");c.push({name:"Dependency Source",value:`\`${i}\`
\`\`\`${p.type}
`+p.code+"\n```"});}if(d){const i=d.file.replace(process.cwd(),"");c.push({name:"Project Source",value:`\`${i}\`
\`\`\`${d.type}
`+d.code+"\n```"});}c.sort((i,v)=>i.name.localeCompare(v.name));const N={color:Colors.Red,fields:c},h=(getState(l+"error_counter")??-1)+1;setState(l+"error_counter",h),setState(`${l}_error_${h}`,{logs:u,stack:m});const k=new ActionRowBuilder().addComponents(new ButtonBuilder({label:"Show stack trace",style:ButtonStyle.Danger,customId:`${l}stack_trace_${h}`}),new ButtonBuilder({label:"Show logs",style:ButtonStyle.Primary,customId:`${l}logs_${h}`}));return {logs:u,message:{content:a,embeds:c.length?[N]:[],components:[k]},stack:m}}async function xe(n){if(!n.isButton()||!n.customId.startsWith(l))return;const e=n.customId.replace(l,""),o=n.message.components[0].components[0].disabled,s=n.message.components[0].components[1].disabled;if(e.startsWith("stack_trace")){const t=e.replace("stack_trace_",""),{stack:r}=getState(`${l}_error_${t}`);await n.update({components:[new ActionRowBuilder().addComponents(new ButtonBuilder({label:"Show stack trace",style:ButtonStyle.Danger,customId:`${l}stack_trace_${t}`,disabled:!0}),new ButtonBuilder({label:"Show logs",style:ButtonStyle.Primary,customId:`${l}logs_${t}`,disabled:s}))]});const a=r.replace("/.robo/build/commands","").replace("/.robo/build/events","").replaceAll(`
`,`
> `);await n.followUp("> ```js\n> "+a+"\n> ```");}else if(e.startsWith("logs")){const t=parseInt(e.replace("logs_",""));await n.update({components:[new ActionRowBuilder().addComponents(new ButtonBuilder({label:"Show stack trace",style:ButtonStyle.Danger,customId:`${l}stack_trace_${t}`,disabled:o}),new ButtonBuilder({label:"Show logs",style:ButtonStyle.Primary,customId:`${l}logs_${t}`,disabled:!0}))]}),D(t,0,n,"new");}else if(e.startsWith("older_logs")){const t=parseInt(e.replace("older_logs_","")),{logIndex:r=0,...a}=getState(`${l}_error_${t}`);setState(`${l}_error_${t}`,{...a,logIndex:r+E}),D(t,r+E,n,"existing");}else if(e.startsWith("newer_logs")){const t=parseInt(e.replace("newer_logs_","")),{logIndex:r=0,...a}=getState(`${l}_error_${t}`);setState(`${l}_error_${t}`,{...a,logIndex:r-E}),D(t,r-E,n,"existing");}}async function D(n,e,o,s){const{logs:t}=getState(`${l}_error_${n}`),r=t.filter(Boolean),a=e+E,u=a<r.length,m=e>0,p=r.slice(e,a).reverse().join(`
> `).substring(0,1986),d=new ActionRowBuilder().addComponents(new ButtonBuilder({label:"Older",style:ButtonStyle.Secondary,customId:`${l}older_logs_${n}`,disabled:!u}),new ButtonBuilder({label:"Newer",style:ButtonStyle.Secondary,customId:`${l}newer_logs_${n}`,disabled:!m}));s==="new"?await o.followUp({content:"> ```\n> "+p+"\n> ```",components:[d]}):s==="existing"&&await o.update({content:"> ```\n> "+p+"\n> ```",components:[d]});}

export { ee as ANSI_REGEX, Z as DEBUG_MODE, be as devLogCommand, Ie as devLogCommandConfig, $e as devRestartCommand, ye as devRestartCommandConfig, _e as devStatusCommand, Ce as devStatusCommandConfig, xe as handleDebugButton, Ee as printErrorResponse, ve as sendDebugError };
//# sourceMappingURL=out.js.map
//# sourceMappingURL=debug.js.map